class Bus {
  constructor() {
    this.cache = {};
  }

  on(name, cb) {
    if (!this.cache[name]) {
      this.cache[name] = [];
    }
    this.cache[name].push(cb);
  }

  emit(name, data) {
    if (this.cache[name]) {
      this.cache[name].forEach((cb) => {
        cb(data);
      });
    }
  }

  off(name, cb) {
    if (this.cache[name]) {
      this.cache[name] = this.cache[name].filter((fn) => {
        return fn !== cb;
      });
    }
  }

  once(name, cb) {
    const fn = (...args) => {
      cb(...args);
      this.off(name, fn);
    };
    this.on(name, fn);
  }
}
